/**
 * 循环添加事件
 */

// 查找到数组形式的列表，存入堆地址0x000，然后为数组中每一个btn开辟堆内存0x001-0x002-0x003，0x000中的数据指向这三个地址
var btns = document.querySelectorAll('button')

// 基础版本，全部都输出3
for (var i = 0; i < btns.length; i++) {
  // 依次循环时创建匿名函数地址0x101-0x102-0x103，让每一个btn的onclick指向对应的地址，然后i值每次+1，最后i=3，所以每个按钮点击时都会找到它们上级的i，输出3
  btns[i].onclick = function () {
    console.log(i)
  }
}

// 使用闭包改造
for (var i = 0; i < btns.length; i++) {
  // 自执行函数会创立一个新的堆空间0x201，以及三个执行上下文EC(AN1)-EC(AN2)-EC(AN3)，并把每次循环的i值声明在对应的执行上下文AO里
  // 闭包的方式只有进栈，没有出栈，会消耗很多内存空间，此时要在循环结束后加上btns=null来释放内存
  (function (i) {
    btns[i].onclick = function () {
      console.log(i)
    }
  })(i)
}
for (var i = 0; i < btns.length; i++) {
  btns[i].onclick = (function (i) {
    return function () {
      console.log(i)
    }
  })(i)
}

// 使用let，let原理和闭包类型，产生独立作用域
for (let i = 0; i < btns.length; i++) {
  btns[i].onclick = function () {
    console.log(i)
  }
}

// 使用自定义属性
for (var i = 0; i < btns.length; i++) {
  // 往已经存在的内存地址0x00i上面添加一个属性值btnIndex存放i值，不会额外开辟内存空间
  btns[i].btnIndex = i
  btns[i].onclick = function () {
    console.log(this.btnIndex)
  }
}

// 使用事件委托，最省内存
document.body.onclick = function (ev) {
  var target = ev.target,
    targetDom = target.tagName
  if (targetDom === 'BUTTON') {
    var index = target.getAttribute('index')
    console.log(index)
  }
}